/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2013-2014 jfinal app. jfapp Group.
 */

package app.models.order;

import app.Const;
import app.constant.OrderConstant;
import app.kit.CommonKit;
import app.kit.TypeKit;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimaps;
import com.jfinal.plugin.activerecord.Model;
import goja.StringPool;
import goja.annotation.TableBind;
import goja.lang.Lang;
import goja.plugins.sqlinxml.SqlKit;
import goja.rapid.db.DaoKit;
import goja.tuples.Pair;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * The table rlo_order mapping model.
 * </p>
 */
@TableBind(tableName = "rlo_order")
public class Order extends Model<Order> {

    /**
     * The public dao.
     */
    public static final Order dao = new Order();

    private static final Function<Order, String> dayFunc = new Function<Order, String>() {
        @Override
        public String apply(Order order) {
            return order.getStr("day");
        }
    };

    private static final long serialVersionUID = 6364988992697186093L;

    public List<Order> findExcelExport() {
        return find(SqlKit.sql("order.findExcelExport"));
    }

    public Order findByOrderNo(String outerOrderNo) {
        return findFirst(SqlKit.sql("order.findByOrderNo"), outerOrderNo);
    }

    public Order findByOrdernoSingle(String outerOrderNo) {
        if(Strings.isNullOrEmpty(outerOrderNo)){
            return null;
        }
        int length = StringUtils.length(outerOrderNo);
        if(length < 24){
            // 24 为订单号长度
            int blank_size = 24 - length;
            for (int i = 0; i < blank_size; i++) {
                outerOrderNo = outerOrderNo + StringPool.SPACE;
            }
        }
        return findFirst(SqlKit.sql("order.findByOrdernoSingle"), outerOrderNo);
    }


    public int findByTransferOrder(int memberProductId){
        Order order = findFirst(SqlKit.sql("order.findByTransferOrder"), memberProductId, OrderConstant.TFR_TYPE, OrderConstant.NEW);
        return TypeKit.getInt(order, Const.FIELD_CNT);
    }

    /**
     * 获取某个会员某个时间的购买金额
     *
     * @param member 会员ID
     * @param start  开始时间
     * @param end    结束时间
     * @return 购买金额
     */
    public BigDecimal sumAmountByMember(int member, DateTime start, DateTime end) {
        Order order = findFirst(SqlKit.sql("order.sumAmountByMember"), member, OrderConstant.TRADE_SUCCESS, start, end);
        return TypeKit.getBigdecimal(order, Const.FIELD_AMOUNT);
    }


    public BigDecimal sumByOrderType() {
        Order order = findFirst(String.format(SqlKit.sql("order.sumByOrderType"), "?,?"), OrderConstant.BUY_TYPE, OrderConstant.TFR_TYPE);
        return TypeKit.getBigdecimal(order, Const.FIELD_AMOUNT);
    }

    public List<Order> statByOrderType(String time, String order_no, String orderType) {

        String stat_sql_tmp = SqlKit.sql("order.statByOrderType");
        StringBuilder whereSql = new StringBuilder(" WHERE ro.status = ? ");
        List<Object> params = Lists.newArrayList();
        params.add(OrderConstant.TRADE_SUCCESS);
        if (!Strings.isNullOrEmpty(time)) {
            final Pair<DateTime, DateTime> times = CommonKit.rangeDatetime(time);
            if(times != null){
                whereSql.append(" AND ro.buy_time BETWEEN ? AND ? ");
                params.add(times.getValue0());
                params.add(times.getValue1());
            }
        }
        if(!Strings.isNullOrEmpty(order_no)){
            whereSql.append(" AND ro.trade_no LIKE ? ");
            params.add(DaoKit.like(order_no));
        }
        if(!Strings.isNullOrEmpty(orderType)){
            if(StringUtils.equals("1", orderType)){
                whereSql.append(" AND ro.order_type = ? ");
                params.add(OrderConstant.CHARGING);
            } else if (StringUtils.equals("2", orderType)){
                whereSql.append(" AND ro.order_type = ? ");
                params.add(OrderConstant.WITHDRAWALS);
            } else if (StringUtils.equals("3", orderType)){
                whereSql.append(" AND ro.order_type IN (?,?,?,?) ");
                params.add(OrderConstant.TFR_PAY_TYPE);
                params.add(OrderConstant.PRODUCTFAIL);
                params.add(OrderConstant.INC_TYPE);
                params.add(OrderConstant.RPN_TYPE);
            } else if (StringUtils.equals("2", orderType)){
                whereSql.append(" AND ro.order_type IN (?,?) ");
                params.add(OrderConstant.BUY_TYPE);
                params.add(OrderConstant.TFR_TYPE);
            }
        }
        String sql = String.format(stat_sql_tmp, whereSql.toString());
        return find(sql, params.toArray());
    }


    /**
     * 首页图表统计
     *
     * @return 半个月的统计数据
     */
    public Optional<ImmutableListMultimap<String, Order>> statByHome(DateTime start, DateTime end) {
        List<Order> orders = find(SqlKit.sql("order.statByDayAndType"), start, end, OrderConstant.BUY_TYPE, OrderConstant.TFR_TYPE);
        if (Lang.isEmpty(orders)) {
            return Optional.absent();
        } else {

            ImmutableListMultimap<String, Order> dayStatAmount = Multimaps.index(orders, dayFunc);
            return Optional.of(dayStatAmount);
        }
    }

    public long countOrderPaySize() {
        Order order = findFirst(SqlKit.sql("order.countOrderByStatusSize"), OrderConstant.TOBEPAY);
        return TypeKit.getLong(order, Const.FIELD_CNT);
    }

    /**
     * 分页查找指定状态的订单
     *
     * @param page     页码
     * @param status   状态
     * @param pageSize 分页大小
     * @return 订单数量
     */
    public List<Order> findByStatus(int page,int status, int pageSize) {

        final Pair<Integer, Integer> offsets = CommonKit.pageOffset(page, pageSize);
        return find(SqlKit.sql("order.findByStatus"), status, offsets.getValue1(), offsets.getValue0());
    }


    public int statByTypeAndProduct(int product, String type, int status){
        Order order = findFirst(SqlKit.sql("order.statByTypeAndProduct"), product, type, status);
        return TypeKit.getInt(order, Const.FIELD_CNT);
    }


    public Order findDetailById(String trade_no) {
        return findFirst(SqlKit.sql("order.findDetailById"), trade_no);
    }

    /**
     * 统计某天的交易额
     *
     * @param daily 交易日起
     * @return 交易额度
     */
    public BigDecimal statByTrade(DateTime daily) {
        DateTime start = daily.millisOfDay().withMinimumValue();
        DateTime end = daily.millisOfDay().withMaximumValue();
        Order order = findFirst(SqlKit.sql("order.statByTrade"), start, end, OrderConstant.BUY_TYPE, OrderConstant.TFR_TYPE);
        return TypeKit.getBigdecimal(order, Const.FIELD_AMOUNT);
    }
}